import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import AsyncCreatableSelect from 'react-select/lib/AsyncCreatable';
import { withStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import TextField from '@material-ui/core/TextField';
import Paper from '@material-ui/core/Paper';
import MenuItem from '@material-ui/core/MenuItem';
import { emphasize } from '@material-ui/core/styles/colorManipulator';
import FormControl from '@material-ui/core/FormControl';
import _ from 'lodash'

const { ipcRenderer } = window.require('electron')

const styles = theme => ({
    formControl: {
        margin: theme.spacing.unit / 4,
    },
    input: {
        display: 'flex',
        padding: 0,
    },
    valueContainer: {
        display: 'flex',
        flexWrap: 'wrap',
        flex: 1,
        alignItems: 'center',
        padding: '27px 12px 10px',
        height: 19,
    },
    chip: {
        margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 4}px`,
    },
    chipFocused: {
        backgroundColor: emphasize(
            theme.palette.type === 'light' ? theme.palette.grey[300] : theme.palette.grey[700],
            0.08,
        ),
    },
    noOptionsMessage: {
        padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`,
    },
    singleValue: {
        fontSize: 16,
    },
    placeholder: {
        position: 'absolute',
        left: 2,
        fontSize: 16,
    },
    paper: {
        position: 'absolute',
        zIndex: 1,
        marginTop: theme.spacing.unit,
        left: 0,
        right: 0,
    },
    divider: {
        height: theme.spacing.unit * 2,
    },
});

function NoOptionsMessage(props) {
    return (
        <Typography
            color="textSecondary"
            className={props.selectProps.classes.noOptionsMessage}
            {...props.innerProps}
        >
            无选项
        </Typography>
    );
}

function inputComponent({ inputRef, ...props }) {
    return <div ref={inputRef} {...props} />;
}

function Control(props) {
    return (
        <TextField
            fullWidth
            variant="filled"
            InputProps={{
                inputComponent,
                inputProps: {
                    className: props.selectProps.classes.input,
                    inputRef: props.innerRef,
                    children: props.children,
                    ...props.innerProps,
                    style: { maxWidth: props.width }
                },
            }}
            {...props.selectProps.textFieldProps}
        />
    );
}

function Option(props) {
    return (
        <MenuItem
            buttonRef={props.innerRef}
            selected={props.isFocused}
            component="div"
            style={{
                fontWeight: props.isSelected ? 500 : 400,
                color: props.isFocused ? 'white' : 'black',
                backgroundColor: props.isFocused ? 'black' : 'white',
            }}
            {...props.innerProps}
        >
            {props.children}
        </MenuItem>
    );
}

function Placeholder(props) {
    return (
        <Typography
            color="textSecondary"
            className={props.selectProps.classes.placeholder}
            {...props.innerProps}
        >
            {props.children}
        </Typography>
    );
}

function SingleValue(props) {
    return (
        <Typography className={props.selectProps.classes.singleValue} {...props.innerProps}>
            {props.children}
        </Typography>
    );
}

function ValueContainer(props) {
    return (
        <div className={props.selectProps.classes.valueContainer}>
            {props.children}
        </div>
    )
}

function Menu(props) {
    return (
        <Paper square className={props.selectProps.classes.paper} {...props.innerProps}>
            {props.children}
        </Paper>
    );
}

function DropdownIndicator(props) {
    return (<div />)
}

const components = {
    Control,
    Menu,
    NoOptionsMessage,
    Option,
    DropdownIndicator,
    Placeholder,
    SingleValue,
    ValueContainer,
};

class MUAsyncSelect extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            selected: null,
        };
    }
    
    componentDidMount() {
        let { defaultValue } = this.props
        if (defaultValue !== undefined) {
            this.setState({
                selected: defaultValue
            })
        }
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== undefined) {
            if (nextProps.value == this.props.value) return;
            this.setState({
                selected: nextProps.value
            })
        }
    }

    handleKeyDown(e) {
        if (e.altKey) {
            if (e.key === 'ArrowLeft') {
                this.handlePreInput(e.target)
            }
            else if (e.key === 'ArrowRight') {
                this.handleNextInput(e.target)
            }
        }
        const { selected } = this.state;
        if (e.key === 'Backspace' && selected !== undefined && selected !== null && (!selected || selected.value === undefined)) {
            this.handlePreInput(e.target);
        }
        else if (e.key === 'Enter') {
            if (this.props.required) {
                if (selected !== undefined && selected !== null && selected.value !== undefined)
                    this.handleNextInput(e.target);
            } else {
                this.handleNextInput(e.target);
            }
        }
    }

    handlePreInput(target) {
        const index = Array.prototype.indexOf.call(target.form, target);
        if (index > 0) {
            target.form.elements[index - 1].focus();
        }
    }

    handleNextInput(target) {
        const index = Array.prototype.indexOf.call(target.form, target);
        if (target.form.elements.length === index + 1) {
            if (this.props.onSubmit) this.props.onSubmit();
        } else if (index + 1 < target.form.elements.length) {
            target.form.elements[index + 1].focus();
        }
    }

    handleChange(name, item) {
        this.setState({
            [name]: item,
        });
        if (this.props.onChange) {
            this.props.onChange(item);
        }
    };

    loadOptions(val, cb) {
        let datas = []
        try {
          datas = JSON.parse(ipcRenderer.sendSync('url', `${this.props.url}?search=${val}`)).datas
        } catch(e) { cb ([])}
        const dd = []
        _.forEach(datas, (ele, idx) => {
            dd.push(ele)
            dd[idx].label = `${ele.fullname}<${ele.age}岁>`
            dd[idx].value = ele._id
        })
        console.log(dd, datas)
        cb(dd)
    }

    render() {
        const { classes, theme } = this.props;

        const selectStyles = {
            input: base => ({
                ...base,
                color: theme.palette.text.primary,
                '& input': {
                    font: 'inherit',
                },
            }),
        };

        return (
            <FormControl className={classes.formControl}>
                <AsyncCreatableSelect
                    classes={classes}
                    styles={selectStyles}
                    textFieldProps={{
                        label: this.props.label,
                        required: this.props.required,
                        InputLabelProps: {
                            shrink: true,
                        },
                        style: { width: this.props.width, height: this.props.dense ? 40 : 80 }
                    }}
                    cacheOptions
                    formatCreateLabel={(val) => `新建:${val}`}
                    loadOptions={(val, cb) => this.loadOptions(val, cb)}
                    components={components}
                    value={this.state.selected}
                    onChange={(item) => this.handleChange('selected', item)}
                    onKeyDown={(e) => this.handleKeyDown(e)}
                    placeholder={this.props.placeholder || ''}
                    // {...this.props}
                />
            </FormControl>
        );
    }
}

MUAsyncSelect.propTypes = {
    classes: PropTypes.object.isRequired,
    theme: PropTypes.object.isRequired,
    dense: PropTypes.bool,
};

export default withStyles(styles, { withTheme: true })(MUAsyncSelect);